package photostock.control;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;

import photostock.model.ItemInfo;
import photostock.model.UserItem;

/**
 *	Cache pouvant contenir 500 items
 */
public class ItemCache implements Serializable {

	private static final long serialVersionUID = 20090501L;
	private static long LIFETIME =  172800L;
	private static int SIZE = 500;
	
	private volatile Hashtable<String, CachedItem> itemsInCache;
	private volatile static ItemCache instance;
	
	private ItemCache() {
		itemsInCache = new Hashtable<String, CachedItem>();
	}

	public static ItemCache getInstance() {
        if (null == instance) {
            synchronized(ItemCache.class) {
                if (null == instance) instance = new ItemCache();
            }
        }
        return instance;
    }
	
	public void addToCache(UserItem item) {
		synchro();
		synchronized(ItemCache.class) {
			if (null != item && !isInCache(item.getName()+ item.getId()))
				itemsInCache.put(item.getName() + item.getId(), new CachedItem(item));
			else itemsInCache.get(item.getName() + item.getId()).setInfos(item.getInfos());
		}
	}
	
	public synchronized UserItem getFromCache(String s) {
		if (isInCache(s)) {
			return itemsInCache.get(s).item;
		}
		return null;
	}
	
	public synchronized void removeFromCache(CachedItem item) {
		if (isInCache(item.getName()+item.getId()))
			itemsInCache.remove(item.getName()+item.getId());
	}

	public synchronized void removeFromCache(UserItem item) {
		if (isInCache(item.getName()+item.getId()))
			itemsInCache.remove(item.getName()+item.getId());
	}

	public boolean isInCache(String s) {
		return itemsInCache.containsKey(s);
	}
	

	private void synchro() {
		java.util.Date now = new java.util.Date();
		long tmpTime = now.getTime() - LIFETIME;
		synchronized(ItemCache.class) {
			while(itemsInCache.size() > SIZE){
				clear(tmpTime);
				tmpTime += 7200000;
			}
		}
	}
	
	private void clear(long t) {
		for (Enumeration<CachedItem> p = itemsInCache.elements(); p.hasMoreElements();) {
			CachedItem tmp = p.nextElement();
			if (tmp.getDateIn().getTime() < t) {
				removeFromCache(tmp);
			}
		}
	}
	
	class CachedItem implements Serializable {
		
		private static final long serialVersionUID = 20090501L;
		private UserItem item;
		private java.util.Date d;
		
		public CachedItem(UserItem p) {
			this.item = p;
			d = new java.util.Date();
		}
		
		public java.util.Date getDateIn() {
			return d;
		}
		
		public String getName() {
			return this.item.getName();
		}
		
		public int getId() {
			return item.getId();
		}
		
		public void setInfos(ItemInfo infos) {
			this.item.setInfos(infos);
		}
	}
}
